package com.yonyou.pmclouds.siteinspection.service.rmiimpl;

import com.alibaba.dubbo.config.annotation.Service;
import com.yonyou.pmclouds.ApplicationConsts;
import com.yonyou.pmclouds.basecom.consts.BillTypeConst;
import com.yonyou.pmclouds.basecom.entity.PageObject;
import com.yonyou.pmclouds.basecom.exception.BusinessException;
import com.yonyou.pmclouds.basecom.runtime.RuntimeEnvironment;
import com.yonyou.pmclouds.inspectitem.entity.InspectItemBillStatusConst;
import com.yonyou.pmclouds.inspectitem.entity.InspectItemVO;
import com.yonyou.pmclouds.inspectitem.rmiitf.InspectItemService;
import com.yonyou.pmclouds.organization.entity.OrganizationVO;
import com.yonyou.pmclouds.organization.rmiitf.OrganizationQuery;
import com.yonyou.pmclouds.picture.rmiitf.PictureRemoteService;
import com.yonyou.pmclouds.pmpub.entity.QueryListParam;
import com.yonyou.pmclouds.pmpub.rmiitf.IPageQuerySerivce;
import com.yonyou.pmclouds.procedure.entity.ProcedureRefVO;
import com.yonyou.pmclouds.procedure.entity.ProcedureVO;
import com.yonyou.pmclouds.procedure.rmiitf.ProcedureQuery;
import com.yonyou.pmclouds.project.entity.ProjectVO;
import com.yonyou.pmclouds.project.rmiitf.ProjectSimpleQuery;
import com.yonyou.pmclouds.siteinspection.entity.SiteInspectionListViewVO;
import com.yonyou.pmclouds.siteinspection.entity.SiteInspectionVO;
import com.yonyou.pmclouds.siteinspection.mapper.SiteInspectionMapper;
import com.yonyou.pmclouds.siteinspection.rmiitf.SiteInspectionQuery;
import com.yonyou.pmclouds.workquality.entity.WorkqualityDetailVO;
import com.yonyou.pmclouds.workquality.entity.WorkqualityVO;
import com.yonyou.pmclouds.workquality.service.rmiitf.WorkqualityQueryService;
import org.apache.commons.lang3.ArrayUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;

import java.math.BigDecimal;
import java.util.*;

@Service(version = ApplicationConsts.APPLICATION_VERSION, interfaceClass = SiteInspectionQuery.class)
public class SiteInspectionQueryImpl implements SiteInspectionQuery , IPageQuerySerivce<SiteInspectionVO> {
    @Autowired
    private SiteInspectionMapper mapper;
    @Autowired
    private PictureRemoteService picService;
    @Autowired
    private InspectItemService itemService;
    @Autowired
    private ProjectSimpleQuery projectQuery;
    @Autowired
    private ProcedureQuery processQuery;
    @Autowired
    private WorkqualityQueryService qualityQuery;
    @Autowired
    private OrganizationQuery organizationQuery;

    @Override
    public SiteInspectionListViewVO[] queryByProject(String pk_project) throws BusinessException {
        if (StringUtils.isEmpty(pk_project)) {
            return null;
        }
        SiteInspectionListViewVO[] vos = mapper.selectLists(pk_project);
        if (ArrayUtils.isEmpty(vos)) {
            return null;
        }
        //处理检查标准参照【列表态显示】
        return setInspectStandard(vos);
    }





    @Override
    public SiteInspectionListViewVO[] queryByBillTypeProject(String pkProject, String billType) throws BusinessException {
        if (StringUtils.isEmpty(pkProject)) {
            return null;
        }
        SiteInspectionListViewVO[] vos = mapper.queryByBillTypeProject(pkProject, billType);
        if (ArrayUtils.isEmpty(vos)) {
            return null;
        }
        // 处理图片显示
        fillUnqualifiedPictures(vos);
        //处理检查标准参照【列表态显示】
        return setInspectStandard(vos);
    }

    private  void fillUnqualifiedPictures(SiteInspectionListViewVO[] vos) throws BusinessException {
        String[] pks = new String[vos.length];
        Map<String, SiteInspectionListViewVO> pkMap = new HashMap<>(vos.length);
        for (int i = 0; i < vos.length; i++) {
            pks[i] = vos[i].getPk_siteinspection();
            pkMap.put(vos[i].getPk_siteinspection(), vos[i]);
        }
        InspectItemVO[] inspectItemVOs = itemService.queryByPkBillsAndStatus(pks, (int) InspectItemBillStatusConst.BILLSTATUS_NO_PASS);
        List<String> itemPks = new ArrayList<>(inspectItemVOs.length);
        for (InspectItemVO item : inspectItemVOs) {
            if (item.getPhotostatus() != InspectItemBillStatusConst.STATUS_HAS_PHOTO) {
                continue;
            }
            itemPks.add(item.getPk_inspectitem());
        }
        Map<String, List<String>> itemPicMap = picService.queryPicsByPkEntitys(itemPks.toArray(new String[0]));
        Map<String, List<String>> billPicMap = new HashMap<>(vos.length);
        for (InspectItemVO item : inspectItemVOs) {
            if (item.getPhotostatus() != InspectItemBillStatusConst.STATUS_HAS_PHOTO) {
                continue;
            }
            List<String> pics = itemPicMap.get(item.getPk_inspectitem());
            if (pics == null || pics.isEmpty()) {
                // 应该不会到这里，但是保险起见
                continue;
            }

            //pics是有值的  billPics是没值的 二者都是ArrayList
            List<String> billPics = billPicMap.get(item.getPk_bill());
            if (billPics == null) {
                billPics = new ArrayList<>();
                billPicMap.put(item.getPk_bill(), billPics);
            }
            if (billPics.size() >= 9) {
                continue;
            }
            billPics.addAll(pics.subList(0, Math.min(pics.size(), 9 - billPics.size())));
        }
        for (SiteInspectionListViewVO vo : vos) {
            List<String> pics = billPicMap.get(vo.getPk_siteinspection());
            if (pics == null || pics.isEmpty()) {
                continue;
            }
            vo.setPictures(pics.toArray(new String[0]));
        }
    }




    @Override
    public SiteInspectionVO queryOne(String pk_siteinspection) throws BusinessException {
        SiteInspectionVO vo = mapper.getById(pk_siteinspection);
        String pk_bill = vo.getPk_siteinspection();
        // 查询检查项
        InspectItemVO[] itemVOs = itemService.queryByPkbill(pk_bill);
        // 查询照片
        vo.setPictures(queryPics(pk_bill));
        vo.setInspectitems(itemVOs);
        // 处理参照字段
        return setRefFiledINfo(vo);
    }

    @Override
    public InspectItemVO queryItemDetail(String pk_inspectItem) throws BusinessException {
        InspectItemVO itemVO = itemService.queryOne(pk_inspectItem);
        return itemVO;
    }

    @Override
    public boolean queryRefByIds(String code, String[] ids) throws BusinessException {
        boolean flag = false;
        Integer count = mapper.selectRefByCode(code, ids);
        if (count != null && count > 0) {
            flag = true;
        }
        return flag;
    }

    @Override
    public PageObject<Object> queryByCondition(String[] pkProjects, String billType, String[] creators, String startDate, String endDate, int[] billStatus, int pageStart, int pageSize) throws BusinessException {

        int count = mapper.countByCondition(pkProjects,billType, creators, startDate, endDate, billStatus);
        SiteInspectionVO[] siteInspectionVOs = mapper.queryByCondition(pkProjects,billType,creators,startDate,endDate,billStatus,pageStart,pageSize);

        return new PageObject<Object>(setRefFiledInfo(siteInspectionVOs),count,pageStart);
    }

    private String[] queryPics(String pk_bill) {
        return picService.queryPicNamesByPkEntity(pk_bill);
    }

    /**
     * 处理参照字段，非必输项需校验空
     *
     * @param vo
     * @return
     * @throws BusinessException
     */
    private SiteInspectionVO setRefFiledINfo(SiteInspectionVO vo) throws BusinessException {
        if (vo == null) {
            return null;
        }
        // 工序
        String pk_process = vo.getPk_process();
        if (!StringUtils.isEmpty(pk_process)) {
            ProcedureVO process = processQuery.getById(pk_process);
            vo.setProcess_name(process.getSname());
        }
        // 项目
        ProjectVO projectVO = projectQuery.queryProject(vo.getPk_project());
        vo.setProject_code(projectVO.getScode());
        vo.setProject_name(projectVO.getSname());
        vo.setManager(projectVO.getManager());

        String pkOrg = projectVO.getPkOrg();
        if(StringUtils.isNotEmpty(pkOrg)) {
            OrganizationVO organizationVO = organizationQuery.queryByPkSrc(RuntimeEnvironment.getTenantId(), pkOrg);
            vo.setOrgName(organizationVO==null?null:organizationVO.getSname());
        }



        //质量标准名称
        WorkqualityVO workqualityVO = qualityQuery.queryByID(vo.getPk_inspectstandard());
        vo.setInspectstandard_name(workqualityVO.getCheckname());
        // 处理检查项名称及描述
        InspectItemVO[] inspectitems = vo.getInspectitems();
        setItemFields(workqualityVO.getItemtabledata(), inspectitems);
        return vo;
    }

    /**
     * 处理参照字段，非必输项需校验空
     *
     * @param vos
     * @return
     * @throws BusinessException
     */
    private SiteInspectionVO[] setRefFiledInfo(SiteInspectionVO[] vos) throws BusinessException {
        if (ArrayUtils.isEmpty(vos)) {
            return new SiteInspectionVO[0];
        }

        Set<String> procSet = new HashSet<String>();
        Set<String> projectSet = new HashSet<String>();
        Set<String> standardSet = new HashSet<String>();
        Set<String> pkSet = new HashSet<String>();

        for (SiteInspectionVO vo:
                vos) {
            procSet.add(vo.getPk_process());
            projectSet.add(vo.getPk_project());
            standardSet.add(vo.getPk_inspectstandard());
            pkSet.add(vo.getPk_siteinspection());
        }

        Map<String,ProcedureRefVO>  procedureRefVOMap = processQuery.queryRefs(procSet.toArray(new String[0]));

        Map<String,ProjectVO> projectVOMap = projectQuery.queryProjects(projectSet.toArray(new String[0]));

        Map<String,WorkqualityVO> workqualityVOMap = qualityQuery.queryByIDs(standardSet.toArray(new String[0]));

        InspectItemVO[] itemVOs  =itemService.queryByPkBillsAndStatus(pkSet.toArray(new String[0]),null);

        Map<String,Integer> itemNumsMap = new HashMap<String,Integer>();
        Map<String,Integer> passNumsMap = new HashMap<String,Integer>();

        String tempPkBill = "";
        for (InspectItemVO itemVO :
                itemVOs) {
            tempPkBill = itemVO.getPk_bill();
            if(itemNumsMap.get(tempPkBill) == null){
                itemNumsMap.put(tempPkBill,0);
            }

            if(InspectItemBillStatusConst.BILLSTATUS_NOT_FIT != itemVO.getBillstatus()){
                int num = itemNumsMap.get(tempPkBill) +1;
                itemNumsMap.put(tempPkBill,num);

                if(InspectItemBillStatusConst.BILLSTATUS_PASS == itemVO.getBillstatus()){
                    if(passNumsMap.get(tempPkBill) == null){
                        passNumsMap.put(tempPkBill,0);
                    }
                    int passNum = passNumsMap.get(tempPkBill)+1 ;
                    passNumsMap.put(tempPkBill,passNum);
                }

            }
        }

        for (SiteInspectionVO vo:
                vos) {
            vo.setProcess_name(procedureRefVOMap.get(vo.getPk_process()) == null ? null:procedureRefVOMap.get(vo.getPk_process()).getSname());
            vo.setProject_name(projectVOMap.get(vo.getPk_project()) == null ? null:projectVOMap.get(vo.getPk_project()).getSname());
            vo.setProject_code(projectVOMap.get(vo.getPk_project()) == null ? null:projectVOMap.get(vo.getPk_project()).getScode());
            vo.setInspectstandard_name(workqualityVOMap.get(vo.getPk_inspectstandard()) == null ? null : workqualityVOMap.get(vo.getPk_inspectstandard()).getCheckname());
            vo.setTotItemNum(itemNumsMap.get(vo.getPk_siteinspection()) == null ? 0 : itemNumsMap.get(vo.getPk_siteinspection()));
            vo.setPassNum(passNumsMap.get(vo.getPk_siteinspection()) == null ?0 :passNumsMap.get(vo.getPk_siteinspection()));
            vo.setUnPassNum(vo.getTotItemNum()-vo.getPassNum());

            if(0 == vo.getTotItemNum() ){
                vo.setPassRate(BigDecimal.ZERO);
            }else{
                vo.setPassRate(new BigDecimal(( (double)vo.getPassNum()/(double)vo.getTotItemNum())*100).setScale(2, BigDecimal.ROUND_HALF_UP));
            }

         }

        return vos;
    }

    private InspectItemVO[] setItemFields(WorkqualityDetailVO[] itemtabledata,
                                          InspectItemVO[] inspectitems) {
        if (ArrayUtils.isEmpty(inspectitems)) {
            return null;
        }
        Map<String, WorkqualityDetailVO> qualityMap = new HashMap<String, WorkqualityDetailVO>();
        for (WorkqualityDetailVO workqualityDetailVO : itemtabledata) {
            qualityMap.put(workqualityDetailVO.getPkWorkqualitydetail(), workqualityDetailVO);
        }
        for (InspectItemVO itemVO : inspectitems) {
            WorkqualityDetailVO detailVO = qualityMap.get(itemVO.getPk_item());
            itemVO.setItem_content(detailVO.getCheckdescription());
            itemVO.setItem_name(detailVO.getCheckitem());
            itemVO.setExamplePictures(detailVO.getExamplePictures());
        }
        return inspectitems;
    }

    private SiteInspectionListViewVO[] setInspectStandard(SiteInspectionListViewVO[] vos) throws BusinessException {
        if (ArrayUtils.isEmpty(vos)) {
            return null;
        }
        HashSet<String> pkSet = new HashSet<>();
        for (SiteInspectionListViewVO siteInspectionListViewVO : vos) {
            pkSet.add(siteInspectionListViewVO.getPk_inspectstandard());
        }

        Map<String, WorkqualityVO> workqualityVOMap = qualityQuery.queryByIDs(pkSet.toArray(new String[0]));
        for (SiteInspectionListViewVO siteInspectionListViewVO : vos) {
            WorkqualityVO workqualityVO = workqualityVOMap.get(siteInspectionListViewVO.getPk_inspectstandard());
            if (workqualityVO != null) {
                siteInspectionListViewVO.setInspectstandard_name(workqualityVO.getCheckname());
            }
        }
        return vos;
    }

    @Override
    public int countByProject(QueryListParam param) throws BusinessException{

        int count = mapper.countByCondition( new String[]{param.getPkProject()}, param.getBillType(),null,  param.getStartDate(), param.getEndDate(), null);

        return count;
    }

    @Override
    public SiteInspectionVO[] queryByProject(QueryListParam param) throws BusinessException {
        SiteInspectionVO[] vos = mapper.queryByCondition(new String[]{param.getPkProject()},param.getBillType(), null,  param.getStartDate(), param.getEndDate(), null,param.getPageStart(),param.getPageSize());
        setInspectStandard(vos);

        return vos;
    }

    private SiteInspectionVO[] setInspectStandard(SiteInspectionVO[] vos) throws BusinessException {
        if (ArrayUtils.isEmpty(vos)) {
            return null;
        }
        HashSet<String> pkSet = new HashSet<>();
        for (SiteInspectionVO vo : vos) {
            pkSet.add(vo.getPk_inspectstandard());
        }

        Map<String, WorkqualityVO> workqualityVOMap = qualityQuery.queryByIDs(pkSet.toArray(new String[0]));
        for (SiteInspectionVO vo : vos) {
            WorkqualityVO workqualityVO = workqualityVOMap.get(vo.getPk_inspectstandard());
            if (workqualityVO != null) {
                vo.setInspectstandard_name(workqualityVO.getCheckname());
            }
        }
        return vos;
    }

    @Override
    public String getBillType() {
        return BillTypeConst.SITEINSPECTION_BILLTYPE;
    }
}
